package org.utils.cmdline;

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class CommandBase {

//collaborators
    public static List asList(Object[] array) {
	return java.util.Arrays.asList(array);
    }

    public static void fillArray(Object[] array,Object typicalInstance) {
	java.util.Arrays.fill(array,typicalInstance);
    }

    public static Collection newCollection() {
	return new java.util.Vector();
    }

    public static Map newMap() {
	return new java.util.Hashtable();
    }
//
//    public static IllegalArgumentException
//		newIllegalArgumentException(String message) {
//	return new IllegalArgumentException(message);
//    }
//
//    public static IllegalArgumentException
//		newIllegalArgumentExceptionNull(Object context) {
//	return newIllegalArgumentException(nullMessage(context));
//    }
//
//    public static IllegalArgumentException
//		newIllegalArgumentExceptionLength(Object context) {
//	return newIllegalArgumentException(lengthMessage(context));
//    }
//
//    public static NumberFormatException
//		    newNumberFormatException(String message) {
//	return new NumberFormatException(message);
//    }

//    public static String newString() {
//    	return new String();
//    }

    public static String[] newStringArray(int length) {
	String[] result = new String[length];
	fillArray(result,"");
	return result;
    }

//constants
    public static String notGreaterThanMessage
				    (int test,int control,Object context) {
	    return "value " +test+ " must be > " +control+ " in " + context;
    }

    public static String lengthMessage(Object context) {
	return "Parameter in " + context + " not allowed to have length zero";
    }

    public static String nullMessage(Object context) {
	return "Parameter in " + context + " not allowed to be null.";
    }

    public static boolean no() {
	return false;
    }

    public static boolean yes() {
	return true;
    }

    public static int zero() {
	return 0;
    }

//simple manipulation
    public static int negate(int anInteger) {
	return -1 * anInteger;
    }

//testing
    public static void checkIntegerGreaterThan(int test,int control,
			    Object context) throws RuntimeException {
		throwExceptionWhen(
			test < control,
			new NumberFormatException(notGreaterThanMessage(test,control,context))
		);
    }

    public static void checkIntegerIsNegative(int anInteger,Object context)
						throws RuntimeException {
		checkIntegerIsPositive(negate(anInteger),
		    context.toString() + "(value inverted for check)");
    }

    public static void checkIntegerIsPositive(int anInteger,Object context)
						throws RuntimeException {
		checkIntegerGreaterThan(anInteger,zero(),context);
    }

    public static void checkStringSubstance(String aString,Object context)
				    throws RuntimeException {
		checkStringIntegrity(aString,context);
		checkStringLength(aString,context);
    }

    public static void checkStringIntegrity(String aString,Object context)
				    throws RuntimeException {
		throwExceptionWhen(
			aString == null,
			new IllegalArgumentException( nullMessage(context) )
		);
    }

    public static void checkStringLength(String aString,Object context)
				    throws RuntimeException {
		throwExceptionWhen(
			aString.length() == 0,
			new IllegalArgumentException(lengthMessage(context))
		);
    }

    public static void throwExceptionWhen(boolean shouldThrow,
			RuntimeException exception) throws RuntimeException {
		if (shouldThrow) {
		    throw exception;
		}
    }

    public static Object defaultWhenNull(Object anyObject,Object onNull) {
		if (anyObject == null) {
		    return onNull;
		}
		return anyObject;
    }

//dealing with exceptions
    public static void silentDealWithException(Throwable exception) {
    }

    public static void gentleDealWithException(Throwable exception) {
		log(exception.getLocalizedMessage());
    }

    public static void dealWithException(Throwable exception) {
		gentleDealWithException(exception);
		exception.printStackTrace(errorStream());
    }

    public static void terminalDealWithException(Throwable exception) {
		out("Unable to handle exception");
		dealWithException(exception);
		exit(1);
    }


//system interaction
    public static PrintStream outStream() {
		return System.out;
    }

    public static PrintStream errorStream() {
		return System.err;
    }

    public static InputStream inStream() {
		return System.in;
    }

    public static void out(Object message) {
		outStream().println(message);
    }

    public static void error(Object message) {
		errorStream().println(message);
    }

    public static void log(Object message) {
		outStream().println(message);
    }

    public static void exit(int condition) {
		System.exit(condition);
    }
}

